﻿
#include "Start_Taskkill.h"
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <exception>
#include "objbase.h"    //CoTaskMemAlloc
#include <ctype.h>  //__isascii 和iswascii
#include <winbase.h>  
#include <tlhelp32.h>  
#include <comdef.h>
#include<fstream>      
#pragma warning(disable: 4996)    
#define COMPILE_MULTIMON_STUBS
#include <MultiMon.h>

typedef struct
{
	HWND hWnd;
	DWORD dwPid;
}WNDINFO;

int numScreen = 0;
RECT rect[2];
void wLog(char *str)//log日志
{
	FILE *fd;
	char buf[64];
	fd = fopen("DLLlog.txt", "at");
	if (NULL == fd)
	{
		printf("open file error!/n");
	}
	fwrite(str, strlen(str), 1, fd);
	char* r = "\n";
	fwrite(r, strlen(r), 1, fd);
	fclose(fd);

}
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor,//回掉函数，用于查询保存屏幕信息
	HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
	static BOOL first = TRUE;   //标志

	//保存显示器信息
	MONITORINFO monitorinfo;
	monitorinfo.cbSize = sizeof(MONITORINFO);

	//获得显示器信息，将信息保存到monitorinfo中
	GetMonitorInfo(hMonitor, &monitorinfo);

	//若检测到主屏
	if (monitorinfo.dwFlags == MONITORINFOF_PRIMARY)
	{
		if (first)  //第一次检测到主屏
		{
			first = FALSE;
			numScreen = 1;

			//将显示器的分辨率信息保存到rect
			rect[0] = monitorinfo.rcMonitor;
			return TRUE;

		}
		else //第二次检测到主屏,说明所有的监视器都已经检测了一遍，故可以停止检测了
		{
			first = TRUE;    //标志复位
			return FALSE;    //结束检测
		}
	}

	rect[numScreen] = monitorinfo.rcMonitor;
	numScreen++;
	return TRUE;
}


BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)//查询窗口句柄
{
	WNDINFO* pInfo = (WNDINFO*)lParam;
	DWORD dwProcessId = 0;
	GetWindowThreadProcessId(hWnd, &dwProcessId);
	if (dwProcessId == pInfo->dwPid)
	{
		wLog("成功查询到启动窗口进程1：");
		char d[10];
		ultoa(dwProcessId, d, 10);
		wLog(d);
		pInfo->hWnd = hWnd;
		return FALSE;
	}
	return TRUE;
}

HWND GetHwndByProcessId(DWORD dwProcessId)//根据进程id查询窗口句柄
{
	WNDINFO info = { 0 };
	info.hWnd = NULL;
	info.dwPid = dwProcessId;
	EnumWindows(EnumWindowsProc, (LPARAM)&info);
	return info.hWnd;
}
HWND GetHwndByPid(DWORD dwProcessID)
{
	//返回Z序顶部的窗口句柄  
	HWND hWnd = ::GetTopWindow(0);
	while (hWnd)
	{
		DWORD pid = 0;
		//根据窗口句柄获取进程ID  
		DWORD dwTheardId = ::GetWindowThreadProcessId(hWnd, &pid);
		if (dwTheardId != 0)
		{
			if (pid == dwProcessID)
			{
				wLog("成功查询到启动窗口进程2：");
				char d[10];
				ultoa(dwTheardId, d, 10);
				wLog(d);
				return hWnd;
			}
		}
		//返回z序中的前一个或后一个窗口的句柄  
		hWnd = ::GetNextWindow(hWnd, GW_HWNDNEXT);
	}
	return hWnd;
}



HWND reGetHwnd(std::string path)
{

	int ID = 0;
	//进程列举  
	int end = path.find_last_of("\\");
	std::string exeName = path.substr(end + 1, path.length() - end - 1);
	path = path.substr(end + 1, path.length() - end - 5);

	const char *cPath = path.c_str();
	wLog(const_cast<char*>(cPath));
	HANDLE hSnApshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnApshot != INVALID_HANDLE_VALUE)
	{
		PROCESSENTRY32 te = { sizeof(te) };
		BOOL f0k = Process32First(hSnApshot, &te);
		for (; f0k; f0k = Process32Next(hSnApshot, &te))
		{
			wprintf(L"Pid: %d %s\n", te.th32ProcessID, te.szExeFile);
			int size = WideCharToMultiByte(CP_ACP, 0, te.szExeFile, -1, NULL, 0, NULL, NULL);
			char *ch = new char[size + 1];
			if (WideCharToMultiByte(CP_ACP, 0, te.szExeFile, -1, ch, size, NULL, NULL))
			{
				if (strstr(ch, cPath))
				{
					char d[10];
					ID = te.th32ProcessID;
					const char* c_exeName = exeName.c_str();
					wLog(const_cast<char*>(c_exeName));
					wLog(ch);
					ID = te.th32ProcessID;
					ultoa(ID, d, 10);
					wLog(d);
					if (memcmp(ch, c_exeName, strlen(ch)) != 0)
					{
						HANDLE hProcess;
						hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ID);
						wLog("compare !!! GetHwndByProcessId... ");
						WaitForInputIdle(hProcess, INFINITE);//等待程序启动完毕
						CloseHandle(hProcess);
						CloseHandle(hSnApshot);
						return GetHwndByProcessId(ID);//获取游戏窗口句柄
					}

				}
			}
		}
	}
	CloseHandle(hSnApshot);
	return NULL;
}
void   DLLStartPro(char* cPath)
{
	try{
		//保存显示器信息
		MONITORINFO monitorinfo;
		monitorinfo.cbSize = sizeof(MONITORINFO);
		const int loopNmu = 2000;
		EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);//查询显示器个数

		HWND activeWnd = GetActiveWindow();//获取活动窗体
		PROCESS_INFORMATION pro_info; //进程信息  
		STARTUPINFO sti; //启动信息  
		//......  
		// 初始化两个结构体  
		ZeroMemory(&pro_info, sizeof(PROCESS_INFORMATION));
		ZeroMemory(&sti, sizeof(STARTUPINFO));

		_bstr_t bstr(cPath);
		LPTSTR lptstr = (LPTSTR)bstr;
		CreateProcess(lptstr, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sti, &pro_info);//启动游戏进程
		printf("%s\n", cPath);
		HWND hwnd = NULL;
		DWORD rc = WaitForInputIdle(pro_info.hProcess, INFINITE);//等待程序启动完毕
		printf("%s%d\n", "开启进程ID:", pro_info.dwProcessId);
		if (rc == 0)
		{
			hwnd = GetHwndByProcessId(pro_info.dwProcessId);//获取游戏窗口句柄
			if (hwnd == NULL)
			{
				Sleep(30000);
				printf("%s\n", "hwnd is null!reGetHwnd...");
				std::string path(cPath);
				hwnd = reGetHwnd(path);//获取游戏窗口句柄
			}
		}
		else
		{
			printf("%s%d\n", "错误码", GetLastError());
		}

		if (numScreen != 2)
		{
			wLog("find screen again!");
			printf("%s\n", "find screen again!");
			EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);
		}
		if (!::MoveWindow(hwnd, rect[1].left, rect[1].top, rect[1].right, rect[1].bottom, TRUE))
		{
			WCHAR word = GetLastError();
			printf("%s\n", "can not move!");

		}
		ShowWindow(hwnd, SW_MAXIMIZE);//窗口最大化
		::SetForegroundWindow(activeWnd);  // 此API 激活我们的窗口
		::SetActiveWindow(activeWnd);
		printf("%s\n", "startPro end!");
	}
	catch (...)
	{
		WCHAR word = GetLastError();

	}

}
void    DLLTaskKill(char* cname)
{
	int ID = 0;
	//进程列举  
	printf("%s\n", cname);
	std::string name(cname);
	if (name.find(".exe"))
	{
		name = name.substr(0, name.length() - 4);
	}
	const char *cPath = name.c_str();
	printf("%s\n", cPath);
	HANDLE hSnApshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnApshot != INVALID_HANDLE_VALUE)
	{
		PROCESSENTRY32 te = { sizeof(te) };
		BOOL f0k = Process32First(hSnApshot, &te);
		for (; f0k; f0k = Process32Next(hSnApshot, &te))
		{
			wprintf(L"Pid: %d %s\n", te.th32ProcessID, te.szExeFile);
			int size = WideCharToMultiByte(CP_ACP, 0, te.szExeFile, -1, NULL, 0, NULL, NULL);
			char *ch = new char[size + 1];
			if (WideCharToMultiByte(CP_ACP, 0, te.szExeFile, -1, ch, size, NULL, NULL))
			{
				if (strstr(ch, cPath))//。
				{
					ID = te.th32ProcessID;
					HANDLE hProcess;
					// 现在我们用函数 TerminateProcess()终止进程：
					// 这里我们用PROCESS_ALL_ACCESS
					hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ID);
					TerminateProcess(hProcess, 0);
					CloseHandle(hProcess);
				}
			}
		}
	}
	CloseHandle(hSnApshot);
}

